package cn.ray_land.dlprint.print;

import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.Semaphore;

import cn.ray_land.dlprint.app.App;
import cn.ray_land.dlprint.data.SliceData;
import cn.rayland.api.X3gStatus;
import cn.rayland.library.bean.GcodeTask;
import cn.rayland.library.bean.MachineState;
import cn.rayland.library.bean.MachineTask;

import static cn.ray_land.dlprint.util.Preconditions.checkNotNull;

/**
 * Created by gw on 2016/8/3.
 */

public class PrintPresenter implements PrintContract.Presenter {

    private PrintContract.View mView;
    private SliceData mData;
    private GcodeTask mGcodeTask = new GcodeTask();
    private Handler mHandler = new Handler(Looper.getMainLooper());
    private  HandlerThread mPrintThread;
    private Handler mPrintHandler;
    private volatile boolean isPrinting;
    private Semaphore mAllowSend = new Semaphore(1);

    public PrintPresenter(SliceData sliceData, PrintContract.View view){
        checkNotNull(sliceData);
        checkNotNull(view);
        this.mData = sliceData;
        this.mView = view;
        mPrintThread = new HandlerThread("dlp_print_thread");
        mPrintThread.start();
        mPrintHandler = new Handler(mPrintThread.getLooper());
    }

    @Override
    public void startPrint() {
        isPrinting = true;
        mPrintHandler.post(printRunnable);
    }

    @Override
    public void stopPrint() {
        isPrinting = false;
        App.machineManager.cancel(true);
        mPrintThread.quit();
    }

    private Runnable printRunnable = new Runnable() {
        @Override
        public void run() {
            File gcodeFile = mData.getGcodeFile();
            BufferedReader br = null;
            try {
                br = new BufferedReader(new FileReader(gcodeFile));
                String str;
                while((str = br.readLine())!=null && isPrinting){
                    if(!str.startsWith(";")){
                        try {
                            mAllowSend.acquire();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        mGcodeTask.setContent(str);
                        mGcodeTask.setTaskCallback(new MachineTask.TaskCallback() {
                            @Override
                            public void onStart(MachineTask machineTask, X3gStatus x3gStatus) {
                                Log.i("PrintPresenter", "onStart");
                            }

                            @Override
                            public void onError(MachineTask machineTask, MachineState machineState) {
                                Log.i("PrintPresenter", "onError");
                            }

                            @Override
                            public void onCancel(MachineTask machineTask, MachineState machineState) {
                                Log.i("PrintPresenter", "onCancel");
                            }

                            @Override
                            public void onFinished(MachineTask machineTask, MachineState machineState) {
                                Log.i("PrintPresenter", "onFinished");
                                mAllowSend.release();
                            }
                        });
                        App.machineManager.sendTask(mGcodeTask, true);
                    }

                    if(str.startsWith(";<Slice>")){
                        String value = str.substring(str.lastIndexOf(";<Slice>")+8).trim();
                        if(TextUtils.isDigitsOnly(value)){
                            final int indexLevel = value.length();
                            final int index = Integer.parseInt(value);
                            String url = gcodeFile.getAbsolutePath().toLowerCase().replace(".gcode", "");
                            int level = Integer.toString(mData.getLayers()).length()<4?4:Integer.toString(mData.getLayers()).length();
                            String cover = "";
                            for(int i=0;i<level-indexLevel;i++){
                                cover += "0";
                            }
                            url = url + cover + index + ".png";
                            final File imageFile = new File(url);
                            mHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    mView.showImage(Uri.fromFile(imageFile));
                                    mView.showProgressText(index+1, mData.getLayers());
                                }
                            });
                        }
                    }

                    if(str.startsWith(";<Delay>")){
                        String value = str.substring(str.lastIndexOf(";<Delay>")+8).trim();
                        if(TextUtils.isDigitsOnly(value)){
                            int delay = Integer.parseInt(value);
                            Thread.sleep(delay);
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if(br!=null){
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    };
}
